#include "Driver.h"
#include "CancelSafeQueue.h"

extern IO_CSQ g_CancelSafeQueue;
extern PLIST_ENTRY		g_TransportIrpQueue;
extern KSPIN_LOCK		g_QueueLock;

NTSTATUS DispatchCreate(__in PDEVICE_OBJECT pDevice, __in PIRP pIrp)
{
    KdPrint(("[DEBUG] " __FUNCTION__));

    pIrp->IoStatus.Information  = 0;
    pIrp->IoStatus.Status       = STATUS_SUCCESS;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(__in PDEVICE_OBJECT pDevice, __in PIRP pIrp)
{
    KdPrint(("[DEBUG] " __FUNCTION__));

    pIrp->IoStatus.Information  = 0;
    pIrp->IoStatus.Status       = STATUS_SUCCESS;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}


NTSTATUS DispatchDeviceControl(__in PDEVICE_OBJECT pDevice, __in PIRP pIrp)
{
    KdPrint(("[DEBUG] " __FUNCTION__));

    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(pIrp), IrpStackOut;
	PLIST_ENTRY pListEntry, pOldHead;
	PIRP pIrpOut;
	PCHAR pWriteDataBuffer = NULL, pReadDataBuffer = NULL;
	
	IrpStack = IoGetCurrentIrpStackLocation(pIrp);

    //
    // Check parameters
    //

    switch(IrpStack->Parameters.DeviceIoControl.IoControlCode)
    {
	case IOCTL_SET_TRANSPORT_PACKET:
		IoCsqInsertIrp(&g_CancelSafeQueue, pIrp, NULL);
		return STATUS_PENDING;
		break;

	case IOCTL_SIMULATE_ONE_PACKET: 

		pIrpOut = IoCsqRemoveNextIrp(&g_CancelSafeQueue, NULL);
		IrpStackOut = IoGetCurrentIrpStackLocation(pIrpOut);
		
		if(IrpStackOut)
		{
			pWriteDataBuffer = (PCHAR)MmGetSystemAddressForMdlSafe(pIrpOut->MdlAddress, NormalPagePriority);
				
	    
			if(pWriteDataBuffer)
			{         
				RtlCopyMemory(pWriteDataBuffer, pIrp->AssociatedIrp.SystemBuffer, 11);
			}
			pIrpOut->IoStatus.Status	= STATUS_SUCCESS;
			pIrp->IoStatus.Status		= STATUS_SUCCESS;

			IoCompleteRequest(pIrpOut, IO_NO_INCREMENT);
			IoCompleteRequest(pIrp, IO_NO_INCREMENT);
			return STATUS_SUCCESS;
		}
		break;
	}
	KdPrint(("[ERROR] " __FUNCTION__ " STATUS_INVALID_DEVICE_REQUEST"));

    pIrp->IoStatus.Information  = 0;
    pIrp->IoStatus.Status       = STATUS_INVALID_DEVICE_REQUEST;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	
	return STATUS_INVALID_DEVICE_REQUEST;
}
